import json

class JSONParser:

    def __init__(self, data):
        self.data = json.loads(data)
        self.table = []

    def getColumns(self):
        columns = []
        attributes = self.getAttributes(self.data)
        for attr in attributes:
            columns = columns + [[attr[-1],attr]]
        return columns
        

    def getAttributes(self, data):
        table = []
        if type(data) == list and data != []:
            output = self.getAttributes(data[0])
            return self.checkList(output, [0])
        elif type(data) == dict:
            for tag in data:
                output = self.checkList(self.getAttributes(data[tag]), [tag])
                if type(output) == list and output != [] and type(output[0]) == list:
                    table = table + output
                else:
                    table.append(self.checkList(self.getAttributes(data[tag]), [tag]))
            return table
        elif type(data) == unicode or type(data) == str or type(data) == int or type(data) == bool:
            return []
        elif type(data) == type(None) or data == []:
            return []

    def checkList(self, output, addition):
        table = []
        if type(output) == list and output != [] and type(output[0]) == list:
            for item in output:
                if type(item) == list and item != [] and type(item[0]) == list:
                    table = table + self.checkList(item, addition)
                else:
                    table.append(addition + item)
            return table
        return addition + output
    

    def getTable(self, search, searchPath):
        #paths = self.convertPaths(search)
        items = self.getItems(searchPath, self.data)
        columns = []
        for column in search:
            columns.append(column[0])
        dataStore = self.getDataGridStore(columns, items)
        return dataStore

    def getDataGridStore(self, columns, data):
        dataStore = {'items':[]}
        print data
        #print len(columns)
        for row in data:
            fields = {}
            for number in range(0, len(columns)-1):
                fields[columns[number]] = row[number]
            dataStore['items'].append(fields)
        return [columns, dataStore]

    def convertPaths(self, paths):
        head = {}
        for path in paths:
            if not str(path[0]) in head.keys():
                head[path[0]] = []
            head[path[0]].append(path[1:])
        return [path[0]] + self.workPaths(head)

    def workPaths(self, paths):
        pathList = {}
        number = False
        for key in paths.keys():
            #print paths
            for path in paths[key]:
                #print path
                #print path[0]
                if type(path[0]) == int:
                    if not str(path[0]) in pathList.keys():
                        pathList['0'] = []
                    pathList['0'].append(path[1:])
                else:
                    if not str(path[0]) in pathList.keys():
                        pathList[str(path[0])] = []
                    pathList[str(path[0])].append(path[1:])
        path = []
       # print pathList
        scope = False
        for convergentPaths in pathList.keys():
            if pathList[convergentPaths] == [[]] and len(pathList) != 1:
                scope = True
        inte = []
        for convergentPaths in pathList.keys():
            #print pathList[convergentPaths]
            if pathList[convergentPaths] == [[]]:
                inter = [convergentPaths]
            else:
                convertPath = [convergentPaths]
                convertPath = convertPath + self.workPaths({convergentPaths: pathList[convergentPaths]})
                inter = convertPath
            if scope == True:
                path.append(inter)
            else:
                path = path + inter
        return path

    def getItems(self, path, data):
        item = path[0]
        try:
            item = int(item)
        except TypeError, e:
            item = path[0]
        except ValueError, e:
            item = path[0]
        if type(item) == str or type(item) == unicode:
            return self.getString(path, data)
        elif type(item) == int:
            return self.getInteger(path, data)
        elif type(item) == list:
            return self.merge(path, data)

    def merge(self, path, data):
        table = []
        intertable = []
        for item in path:
            tags = self.getItems(item, data)
            if table != []:
                intertable = table
                table = []
                for field in intertable:
                    for tag in self.getItems(item, data):
                        if type(tag) == list:
                            table.insert(0, field + tag)
                        else:
                            table.insert(0, field + [tag])
            else:
                if type(tags[0]) == list:
                    for tag in tags:
                        table.insert(0, tag)
                else:
                    table.insert(0, tags)
        return table

    
    def getInteger(self, path, data):
        if type(data) == dict:
            raise ValueError
        table = []
        for number in range(0, len(data)):
            if type(data[number]) == str or type(data[number]) == unicode or type(data[number]) == int:
                table.append([data[number]])
            elif data[number] == None:
                table.append(["None"])
            else:
                for item in self.getItems(path[1:], data[number]):
                    if type(item) == list:
                        table.append(item)
                    else:
                        table.append([item])
        return table
    

    def getString(self, path, data):
        if type(data) == list:
            raise ValueError
        item = data[path[0]]
        if type(item) == unicode or type(item) == int:
            return [item]
        elif item == None:
            return ["None"]
        else:
            return self.getItems(path[1:], item)

